package deibay.server.network;

import java.io.IOException;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;

import deibay.DeibayLogger;
import deibay.messages.Message;
import deibay.messages.ReplyLoginMsg;
import deibay.network.IClientCommunicator;
import deibay.server.ServerManager;
import deibay.server.eventargs.ReceivedMessageEventArg;
import deibay.server.events.ReceivedMessageEvent;
import deibay.server.network.socket.SocketClientCommunicator;
import deibay.users.User;

/**
 * @author   Joel Cordeiro
 */
public class Session {
	
	protected User user = null;
	protected IClientCommunicator communicator = null;
	/**
	 * @uml.property  name="lastActivity"
	 */
	protected Date lastActivity = null;		
	protected LinkedBlockingQueue<Message> sentMessages = null;
	
	public Session(IClientCommunicator clientCommunicator, User user)
	{
		this.communicator = clientCommunicator;
		this.lastActivity = new Date(System.currentTimeMillis());
		this.sentMessages = new LinkedBlockingQueue<Message>();
		this.user = user;		
	}

	
	/**
	 * @param now
	 * @uml.property  name="lastActivity"
	 */
	public void setLastActivity(Date now)
	{
		this.lastActivity = now;		
	}
	
	/**
	 * @return
	 * @uml.property  name="lastActivity"
	 */
	public Date getLastActivity()
	{
		return this.lastActivity;
	}
	
	public String getUsername()
	{
		return this.user.getId();
	}
	
	public void recoverSession(IClientCommunicator clientCom)
	{
		this.communicator = clientCom;
		this.lastActivity = new Date(System.currentTimeMillis());
		Message temp = sentMessages.poll();
		while(temp!=null)
		{
			sendMessage(temp);
			temp = sentMessages.poll();
		}
		DeibayLogger.getInstance().getLog().log(Level.INFO, "Foi recuperada a sessao do utilizador ["+user.getId()+"]\n");
	}
	
	/**
	 * @return
	 * @uml.property  name="user"
	 */
	public User getUser()
	{
		return user;
	}
	
	/**
	 * @return
	 * @uml.property  name="communicator"
	 */
	public IClientCommunicator getCommunicator()
	{
		return this.communicator;
	}
	
	public synchronized void sendMessage(Message message)
	{
		try {
			sentMessages.offer(message);
			communicator.send(message);
			sentMessages.remove(message);
			this.lastActivity = new Date(System.currentTimeMillis());
		} catch (IOException e) {			
			DeibayLogger.getInstance().getLog().log(Level.SEVERE, "User "+user.getId()+" perdeu a sua ligacao.\n");
		}		
	}	
	
	public void close()
	{
		communicator.close();		
	}
}
